home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-9.10-netbook-remix-PL.iso / casper / filesystem.squashfs / usr / share / pyshared / invest / chart.py < prev    next >
Text File  |  2009-10-20  |  7KB  |  255 lines

  1. #!/usr/bin/env python
  2.  
  3. import gtk, gtk.gdk
  4. import gobject
  5. import os
  6. import invest
  7. from gettext import gettext as _
  8. from invest import *
  9. import sys
  10. from os.path import join
  11. import urllib
  12. from threading import Thread
  13. import time
  14.  
  15. AUTOREFRESH_TIMEOUT = 20*60*1000 # 15 minutes
  16.  
  17. # based on http://www.johnstowers.co.nz/blog/index.php/2007/03/12/threading-and-pygtk/
  18. class _IdleObject(gobject.GObject):
  19.     """
  20.     Override gobject.GObject to always emit signals in the main thread
  21.     by emmitting on an idle handler
  22.     """
  23.     def __init__(self):
  24.         gobject.GObject.__init__(self)
  25.  
  26.     def emit(self, *args):
  27.         gobject.idle_add(gobject.GObject.emit,self,*args)
  28.  
  29. class ImageRetriever(Thread, _IdleObject):
  30.     """
  31.     Thread which uses gobject signals to return information
  32.     to the GUI.
  33.     """
  34.     __gsignals__ =  { 
  35.             "completed": (
  36.                 gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, []),
  37.             # FIXME: should we be making use of this?
  38.             #"progress": (
  39.             #    gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [
  40.             #    gobject.TYPE_FLOAT])        #percent complete
  41.             }
  42.  
  43.     def __init__(self, image_url):
  44.         Thread.__init__(self)
  45.         _IdleObject.__init__(self)    
  46.         self.image_url = image_url
  47.         self.retrieved = False
  48.         
  49.     def run(self):
  50.         self.image = gtk.Image()
  51.         try: sock = urllib.urlopen(self.image_url, proxies = invest.PROXY)
  52.         except Exception, msg:
  53.             invest.debug("Error while opening %s: %s" % (self.image_url, msg))
  54.         else:
  55.             loader = gtk.gdk.PixbufLoader()
  56.             loader.connect("closed", lambda loader: self.image.set_from_pixbuf(loader.get_pixbuf()))
  57.             loader.write(sock.read())
  58.             sock.close()
  59.             loader.close()
  60.             self.retrieved = True
  61.         self.emit("completed")
  62.  
  63. # p:
  64. #  eX = Exponential Moving Average
  65. #  mX = Moving Average
  66. #  b = Bollinger Bands Overlay
  67. #  v = Volume Overlay
  68. #  p = Parabolic SAR overlay
  69. #  s = Splits Overlay
  70. # q:
  71. #  l = Line
  72. #  c = Candles
  73. #  b = Bars
  74. # l:
  75. #  on = Logarithmic
  76. #  off = Linear
  77. # z:
  78. #  l = Large
  79. #  m = Medium
  80. # t:
  81. #  Xd = X Days
  82. #  Xm = X Months
  83. #  Xy = X Years
  84. # a:
  85. #  fX = MFI X days
  86. #  ss = Slow Stochastic
  87. #  fs = Fast Stochastic
  88. #  wX = W%R X Days
  89. #  mX-Y-Z = MACD X Days, Y Days, Signal
  90. #  pX = ROC X Days
  91. #  rX = RSI X Days
  92. #  v = Volume
  93. #  vm = Volume +MA
  94. # c:
  95. #  X = compare with X
  96. #
  97.  
  98. class FinancialChart:
  99.     def __init__(self, ui):
  100.         self.ui = ui
  101.         
  102.         # Window Properties
  103.         win = ui.get_object("window")
  104.         win.set_title(_("Financial Chart"))
  105.         
  106.         try:
  107.             pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(join(invest.ART_DATA_DIR, "invest_neutral.svg"), 96,96)
  108.             self.ui.get_object("plot").set_from_pixbuf(pixbuf)
  109.         except Exception, msg:
  110.             invest.debug("Could not load 'invest-neutral.svg' file: %s" % msg)
  111.             pass
  112.         
  113.         # Defaut comboboxes values
  114.         for widget in ["t", "q"]:
  115.             ui.get_object(widget).set_active(0)
  116.         
  117.         # Connect every option widget to its corresponding change signal    
  118.         symbolentry = ui.get_object("s")
  119.         refresh_chart_callback = lambda w: self.on_refresh_chart()
  120.         
  121.         for widgets, signal in [
  122.             (("pm5","pm10","pm20","pm50","pm100","pm200",
  123.             "pe5","pe10", "pe20","pe50","pe100","pe200",
  124.             "pb","pp","ps","pv",
  125.             "ar","af","ap","aw","am","ass","afs","av","avm"), "toggled"),
  126.             (("t", "q"), "changed"),
  127.             (("s",), "activate"),
  128.         ]:
  129.             for widget in widgets:
  130.                 ui.get_object(widget).connect(signal, refresh_chart_callback)
  131.         
  132.         ui.get_object("progress").hide()
  133.         
  134.         # Connect auto-refresh widget
  135.         self.autorefresh_id = 0
  136.         ui.get_object("autorefresh").connect("toggled", self.on_autorefresh_toggled)
  137.                                         
  138.     def on_refresh_chart(self, from_timer=False):
  139.         tickers = self.ui.get_object("s").get_text()
  140.             
  141.         if tickers.strip() == "":
  142.             return True
  143.         
  144.         # FIXME: We don't just do US stocks, so we can't be this
  145.         # simplistic about it, but it is a good idea.
  146.         #if from_timer and not ustime.hour_between(9, 16):
  147.         #    return True
  148.             
  149.         tickers = [ticker.strip().upper() for ticker in tickers.split(' ') if ticker != ""]
  150.         
  151.         # Update Window Title ------------------------------------------------------
  152.         win = self.ui.get_object("window")
  153.         title = _("Financial Chart - %s")
  154.         titletail = ""
  155.         for ticker in tickers:
  156.             titletail += "%s / " % ticker
  157.         title = title % titletail
  158.         
  159.         win.set_title(title[:-3])
  160.  
  161.         # Detect Comparison or simple chart ----------------------------------------
  162.         opt = ""
  163.         for ticker in tickers[1:]:
  164.             opt += "&c=%s" % ticker
  165.         
  166.         # Create the overlay string ------------------------------------------------
  167.         p = ""
  168.         for name, param in [
  169.             ("pm5",   5),
  170.             ("pm10",  10),
  171.             ("pm20",  20),
  172.             ("pm50",  50),
  173.             ("pm100", 100),
  174.             ("pm200", 200),
  175.             ("pe5",   5),
  176.             ("pe10",  10),
  177.             ("pe20",  20),
  178.             ("pe50",  50),
  179.             ("pe100", 100),
  180.             ("pe200", 200),
  181.             ("pb", ""),
  182.             ("pp", ""),
  183.             ("ps", ""),
  184.             ("pv", ""),
  185.         ]:
  186.             if self.ui.get_object(name).get_active():
  187.                 p += "%s%s," % (name[1], param)
  188.             
  189.         # Create the indicators string ---------------------------------------------
  190.         a = ""
  191.         for name, param in [
  192.             ("ar",  14),
  193.             ("af",  14),
  194.             ("ap",  12),
  195.             ("aw",  14),
  196.             ("am",  "26-12-9"),
  197.             ("ass", ""),
  198.             ("afs", ""),
  199.             ("av",  ""),
  200.             ("avm", ""),
  201.         ]:
  202.             if self.ui.get_object(name).get_active():
  203.                 a += "%s%s," % (name[1:], param)
  204.         
  205.         # Create the image URL -----------------------------------------------------
  206.         chart_base_url = "http://ichart.europe.yahoo.com/z?s=%(s)s&t=%(t)s&q=%(q)s&l=%(l)s&z=%(z)s&p=%(p)s&a=%(a)s%(opt)s"
  207.         url = chart_base_url % {
  208.             "s": tickers[0],
  209.             "t": self.ui.get_object("t").get_active_text(),
  210.             "q": self.ui.get_object("q").get_active_text(),
  211.             "l": "off",
  212.             "z": "l",
  213.             "p": p,
  214.             "a": a,
  215.             "opt": opt,
  216.         }
  217.  
  218.         # Download and display the image -------------------------------------------    
  219.         progress = self.ui.get_object("progress")
  220.         progress.set_text(_("Opening Chart"))
  221.         progress.show()
  222.         
  223.         image_retriever = ImageRetriever(url)
  224.         image_retriever.connect("completed", self.on_retriever_completed)
  225.         image_retriever.start()
  226.  
  227.         # Update timer if needed
  228.         self.on_autorefresh_toggled(self.ui.get_object("autorefresh"))
  229.         return True
  230.     
  231.     def on_retriever_completed(self, retriever):
  232.         self.ui.get_object("plot").set_from_pixbuf(retriever.image.get_pixbuf())
  233.         progress = self.ui.get_object("progress")
  234.         if retriever.retrieved == True:
  235.             progress.set_text(_("Chart downloaded"))
  236.         else:
  237.             progress.set_text(_("Chart could not be downloaded"))
  238.     
  239.     def on_autorefresh_toggled(self, autorefresh):
  240.         if self.autorefresh_id != 0:
  241.             gobject.source_remove(self.autorefresh_id)
  242.             self.autorefresh_id = 0
  243.             
  244.         if autorefresh.get_active():
  245.             self.autorefresh_id = gobject.timeout_add(AUTOREFRESH_TIMEOUT, self.on_refresh_chart, True)
  246.  
  247. def show_chart(tickers):
  248.     ui = gtk.Builder();
  249.     ui.add_from_file(os.path.join(invest.BUILDER_DATA_DIR, "financialchart.ui"))
  250.     chart = FinancialChart(ui)
  251.     ui.get_object("s").set_text(' '.join(tickers))
  252.     chart.on_refresh_chart()
  253.     return ui.get_object("window")
  254.  
  255.